package jogo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;  

import javax.swing.JOptionPane;

public class Tabuleiro{
	
	public static int contadorPossibilidades = 0;
	public Casas casa[] = new Casas[64];
	
	public int movimentos = 0;
	public static Tabuleiro tabuleiroAtual;
	public static int pior=-1000, melhor=-1000;
	public int avaliacao = 0;
	public Jogador jogadorA;
	public Jogador jogadorB;
	public int paiID;
	public int id;
	public List<Casas> listObrigatoriaInicial = new ArrayList<Casas>();
	public List<Casas> listObrigatoriaFinal = new ArrayList<Casas>();
	public Map<Casas, Integer> obrigatoria;
	
	
    public Casas casaInicial = null;
    public Casas casaFinal = null;
    public Casas casaCaptura = null;
    
    public int jogadorAtual =1;
    int max =0;
    
    /**
     * Construtor para clonar tabuleiro
     * @param casa
     * @param movimentos
     * @param avaliacao
     * @param jogadorA
     * @param jogadorB
     */
    public Tabuleiro(Casas casa[], int movimentos, int avaliacao, Jogador jogadorA, Jogador jogadorB){
    	Peças peçaA[] = new Peças[12];
    	Peças peçaB[] = new Peças[12];
    	int contA=0;
    	int contB=0;
    	for(int i=0; i<64; i++){
    		this.casa[i] = new Casas(casa[i].getPeça(), casa[i].getPos(), casa[i].isValida());
    		Peças peça = casa[i].getPeça();
    		if(peça !=null){
	    		if(peça.getId() <12) {
	    			peçaA[peça.getId()] = new Peças(peça.getId(), peça.getJogador(), peça.getPosicao(), peça.isDama());
	    			contA++;
	    		}
	    		else {
	    			peçaB[peça.getId()-12] =new Peças(peça.getId(), peça.getJogador(), peça.getPosicao(), peça.isDama());
	    			contB++;
	    		}
    		}
    	}
    	this.movimentos = movimentos;
    	if(movimentos%2==0) jogadorAtual = 1;
    	else jogadorAtual = -1;
    	this.avaliacao = avaliacao;
    	this.jogadorA = new Jogador(peçaA, 1, 12, contA);
    	this.jogadorB = new Jogador(peçaB, -1, 12, contB);
    }
    /**
     * Construtor para clonar tabuleiro contendo a casaInicial e a casaFinal
     * @param casa
     * @param movimentos
     * @param avaliacao
     * @param jogadorA
     * @param jogadorB
     * @param casaI
     * @param casaF
     */
    public Tabuleiro(Casas casa[], int movimentos, int avaliacao, Jogador jogadorA, Jogador jogadorB, Casas casaI,Casas casaF){
    	Peças peçaA[] = new Peças[12];
    	Peças peçaB[] = new Peças[12];
    	int contA=0;
    	int contB=0;
    	for(int i=0; i<64; i++){
    		this.casa[i] = new Casas(casa[i].getPeça(), casa[i].getPos(), casa[i].isValida());
    		Peças peça = casa[i].getPeça();
    		if(peça !=null){
	    		if(peça.getId() <12) {
	    			peçaA[peça.getId()] = new Peças(peça.getId(), peça.getJogador(), peça.getPosicao(), peça.isDama());
	    			contA++;
	    		}
	    		else {
	    			peçaB[peça.getId()-12] =new Peças(peça.getId(), peça.getJogador(), peça.getPosicao(), peça.isDama());
	    			contB++;
	    		}
    		}
    	}
    	
    	this.movimentos = movimentos;
    	if(movimentos%2==0) jogadorAtual = 1;
    	else jogadorAtual = -1;
    	this.avaliacao = avaliacao;
    	this.jogadorA = new Jogador(peçaA, 1, 12, contA);
    	this.jogadorB = new Jogador(peçaB, -1, 12, contB);
    	this.casaInicial = this.casa[casaI.getPos()];
    	this.casaFinal = this.casa[casaF.getPos()];
    }
	/**
	 * Cria um tabuleiro
	 */
    public Tabuleiro(){
		jogadorA = new Jogador(1);
		jogadorB = new Jogador(-1);
	}
	
    /**
     * Retorna um dos jogadores de acordo com o id deles
     * @param jogador (id)
     * @return jogadorA ou jogadorB
     */
	public Jogador getJogador(int jogador){
		if(jogador == 1) return this.jogadorA;
		else return this.jogadorB;
	}
	
	/**
	 * Função que cria jogdas para a Busca em Largura(BFS)
	 * @param n (número de níveis)
	 * @param movimentos (quantidade de movimentos atual)
	 * @param heuristica (define se usará ou não a heurística)
	 * @return um dos tabuleiros melhor avaliados no nível n
	 */
	public Tabuleiro criarJogadasBFS(int n, int movimentos, boolean heuristica){
		Map<Integer, Tabuleiro> hash = new HashMap<Integer, Tabuleiro>();
		contadorPossibilidades = 0;
		tabuleiroAtual = new Tabuleiro(this.casa, this.movimentos, this.avaliacao, this.jogadorA,this.jogadorB);
		tabuleiroAtual.paiID=0;
		tabuleiroAtual.id=0;
		hash.put(contadorPossibilidades, tabuleiroAtual);
		
		Tabuleiro melhor = new Tabuleiro(this.casa, this.movimentos, this.avaliacao, this.jogadorA,this.jogadorB);
		Jogador jogador;
		List<Tabuleiro> chavesAux = new ArrayList<Tabuleiro>();
		int i =0,j=0;
		chavesAux.add(tabuleiroAtual);
		do{
			for(j=0;j<contadorPossibilidades;j++){
				chavesAux.add(hash.get(j));
			}
			for(Tabuleiro tabuleiro: chavesAux){
				if(tabuleiro.movimentos == movimentos+i){
					if(tabuleiro.movimentos % 2 == 0) jogador = tabuleiro.jogadorA;
					else jogador = tabuleiro.jogadorB;
					tabuleiro.jogadorAtual= jogador.getId();
					tabuleiroAtual =new Tabuleiro(tabuleiro.casa, tabuleiro.movimentos, tabuleiro.avaliacao,tabuleiro.jogadorA,tabuleiro.jogadorB);
					tabuleiro.adicionarJogadasDoJogadorBFS(jogador, hash,heuristica);
				}
			}
			i++;
		}while(i<n);
		
		chavesAux.clear();
		for(j=0;j<contadorPossibilidades;j++){
			chavesAux.add(hash.get(j));
		}
		melhor.avaliacao=-10000;
		int pior =-1000;
		int somaAvaliacao =0;
		int numTabuleiros =0;
		Tabuleiro tabuleiroAux = null;
		for(Tabuleiro tabuleiro: chavesAux){
			if(tabuleiro.movimentos == (movimentos+i)){
				somaAvaliacao+=tabuleiro.avaliacao;
				numTabuleiros++;
				if(pior == -1000) pior= tabuleiro.avaliacao;
				if(pior> tabuleiro.avaliacao) pior = tabuleiro.avaliacao;
				if(melhor.avaliacao <= tabuleiro.avaliacao){ // if(melhor.avaliacao < tabuleiro.avaliacao)
					if(tabuleiro.movimentos!=(movimentos+1)){
						tabuleiroAux = hash.get(tabuleiro.paiID);
						while(tabuleiroAux.movimentos!=(movimentos+1)){
							tabuleiroAux = hash.get(tabuleiroAux.paiID);
						}
						melhor = new Tabuleiro(tabuleiroAux.casa, tabuleiroAux.movimentos, tabuleiroAux.avaliacao, tabuleiroAux.jogadorA, tabuleiroAux.jogadorB);
					}
					else 
					melhor = new Tabuleiro(tabuleiro.casa, tabuleiro.movimentos, tabuleiro.avaliacao, tabuleiro.jogadorA, tabuleiro.jogadorB);
				}
			}
		}
		float media;
		if(numTabuleiros !=0) media  = somaAvaliacao/numTabuleiros;
		else media = 0;
		if(heuristica){
			System.out.println("Melhor avaliação: " + melhor.avaliacao);
			System.out.println("Pior avaliação: " + pior);
			System.out.println("Média avaliação: " + media);
			System.out.println("");
		}
		System.out.println("Possibilidades: "+Tabuleiro.contadorPossibilidades);
		return melhor;
	}

	
	/**
	 * Gera as jogadas para cada jogador seguindo o principio da busca em largura (BFS)
	 * @param jogador
	 * @param hash
	 * @param heuristica
	 */
	void adicionarJogadasDoJogadorBFS(Jogador jogador, Map<Integer, Tabuleiro> hash,boolean heuristica){
		Peças peça = null;
		jogadorAtual = jogador.getId();
		this.obrigatoria = this.verificaObrigatoria(this.getJogador(this.jogadorAtual));
    	
    	Set<Casas> chaves = this.obrigatoria.keySet(); 
		int max = 0;
		int cont=0;
    	for(Casas casa: chaves){
			cont = this.obrigatoria.get(casa);
			if(cont == max) this.listObrigatoriaInicial.add(casa);
			if(cont > max) {
				this.listObrigatoriaInicial.clear();
				this.listObrigatoriaInicial.add(casa);
				max = cont;
			}
		}
		if(listObrigatoriaInicial.isEmpty()){
			for(int i= 0; i< jogador.getCont(); i++){
				peça = jogador.getPeças(i);
				if(peça != null){
					adicionarJogadasPeçaBFS(peça,hash,heuristica);
				}
			}
		}
		else{
			for(Casas casaI: listObrigatoriaInicial){
				casaInicial = casaI;
				criarListaCasasObrigatorias();
				List<Casas> listObrigatoria =listObrigatoriaFinal;
				for(Casas casaF: listObrigatoria){
					casaFinal = casaF;
					int posicao = casaF.getPos();
					int jogadorAux = jogadorAtual;
					boolean dama = casaI.getPeça().isDama();
					Tabuleiro tabuleiro = new Tabuleiro(tabuleiroAtual.casa, tabuleiroAtual.movimentos, tabuleiroAtual.avaliacao,tabuleiroAtual.jogadorA,tabuleiroAtual.jogadorB, casaI,casaF);
					tabuleiro.capturaPeça(dama);
					cont = tabuleiro.verificarObrigatoriedadeAcao(posicao,posicao,jogadorAux,dama,true);
					while(cont>0){
						tabuleiro.casaInicial = tabuleiro.casa[tabuleiro.casaFinal.getPos()];
						tabuleiro.criarListaCasasObrigatorias();
						tabuleiro.casaFinal = tabuleiro.listObrigatoriaFinal.get(0);
						tabuleiro.capturaPeça(dama);
						cont = tabuleiro.verificarObrigatoriedadeAcao(tabuleiro.casaFinal.getPos(),tabuleiro.casaFinal.getPos(),jogadorAux,dama,true);
					}
					
					tabuleiro.avaliacao = avaliacao(tabuleiro);
					tabuleiro.id=contadorPossibilidades;
					tabuleiro.paiID=tabuleiroAtual.id;
					hash.put(contadorPossibilidades, tabuleiro);
					contadorPossibilidades++;
				}
			}
		}
	}
	
	/**
	 * Adiciona na hash os tabuleiros gerados a partir da peça fornecida
	 * @param peça
	 * @param hash
	 * @param heuristica
	 */
	void adicionarJogadasPeçaBFS(Peças peça, Map<Integer, Tabuleiro> hash, boolean heuristica) {
		int posicaoInicial = peça.getPosicao();
		List<Casas> listCasas = listaMovimentoValido(posicaoInicial, peça.isDama(), tabuleiroAtual);
		
		int i =0;
		for(Casas casaF: listCasas){
			Tabuleiro tabuleiro = new Tabuleiro(tabuleiroAtual.casa, tabuleiroAtual.movimentos, tabuleiroAtual.avaliacao,tabuleiroAtual.jogadorA,tabuleiroAtual.jogadorB);
			
			if(tabuleiro.moverPeça(posicaoInicial, casaF.getPos(), jogadorAtual, tabuleiro)){
				tabuleiro.tornarDama(tabuleiro.casa[casaF.getPos()].getPeça(),jogadorAtual);
				i++;
				tabuleiro.movimentos++;
				if(!heuristica) tabuleiro.avaliacao = tabuleiro.avaliacao(tabuleiro);
				else {
					tabuleiro.avaliacao = tabuleiro.calcularValor(tabuleiro);
					if(Tabuleiro.pior > tabuleiro.avaliacao) Tabuleiro.pior = tabuleiro.avaliacao;
					if(Tabuleiro.melhor < tabuleiro.avaliacao) Tabuleiro.melhor = tabuleiro.avaliacao;
				}
				tabuleiro.id=contadorPossibilidades;
				tabuleiro.paiID=tabuleiroAtual.id;
				hash.put(contadorPossibilidades, tabuleiro);
				contadorPossibilidades++;
			}
		}
	}
	
	/**
	 * Função que cria jogdas para a Busca em Profundidade(DFS)
	 * @param n (número de níveis)
	 * @param movimentos (quantidade de movimentos atual)
	 * @return um dos tabuleiros melhor avaliados no nível n
	 */
	public Tabuleiro criarJogadasDFS(int n, int movimentos){
		Map<Integer, Tabuleiro> hash = new HashMap<Integer, Tabuleiro>();
		contadorPossibilidades = 0;
		tabuleiroAtual = new Tabuleiro(this.casa, this.movimentos, this.avaliacao, this.jogadorA,this.jogadorB);
		tabuleiroAtual.paiID=0;
		tabuleiroAtual.id=0;
		hash.put(contadorPossibilidades, tabuleiroAtual);
		
		Tabuleiro melhor = new Tabuleiro(this.casa, this.movimentos, this.avaliacao, this.jogadorA,this.jogadorB);
		Tabuleiro t = new Tabuleiro(this.casa, this.movimentos, this.avaliacao, this.jogadorA,this.jogadorB);
		
		Jogador jogador;
		
		List<Tabuleiro> chavesAux = new ArrayList<Tabuleiro>();
		int j=0;
		chavesAux.add(tabuleiroAtual);
		if(movimentos % 2 == 0) jogador = t.jogadorA;
		else jogador = t.jogadorB;			
		t.adicionarJogadasDoJogadorDFS(jogador, hash,movimentos+n);
		
		melhor.avaliacao=-1000;
		chavesAux.clear();
		for(j=0;j<contadorPossibilidades;j++){
			chavesAux.add(hash.get(j));
		}
		int somaAvaliacao =0;
		int numTabuleiros =0;
		Tabuleiro tabuleiroAux = null;
		for(Tabuleiro tabuleiro: chavesAux){
			if(tabuleiro.movimentos == (movimentos+n)){
				somaAvaliacao+=tabuleiro.avaliacao;
				numTabuleiros++;
				if(melhor.avaliacao <= tabuleiro.avaliacao){ 
					if(tabuleiro.movimentos!=(movimentos+1)){
						tabuleiroAux = hash.get(tabuleiro.paiID);
						while(tabuleiroAux.movimentos!=(movimentos+1)){
							tabuleiroAux = hash.get(tabuleiroAux.paiID);
						}
						melhor = new Tabuleiro(tabuleiroAux.casa, tabuleiroAux.movimentos, tabuleiroAux.avaliacao, tabuleiroAux.jogadorA, tabuleiroAux.jogadorB);
					}
					else {
						melhor = new Tabuleiro(tabuleiro.casa, tabuleiro.movimentos, tabuleiro.avaliacao, tabuleiro.jogadorA, tabuleiro.jogadorB);
					}
				}
			}
		}
		System.out.println("Possibilidades: "+Tabuleiro.contadorPossibilidades);
		return melhor;
	}
	
	/**
	 * Gera as jogadas para cada jogador seguindo o principio da busca em profundidade (DFS)
	 * @param jogador
	 * @param hash
	 * @param heuristica
	 */
	void adicionarJogadasDoJogadorDFS(Jogador jogador, Map<Integer, Tabuleiro> hash, int n){
		Peças peça = null;
		jogadorAtual = jogador.getId();
		
		this.obrigatoria = this.verificaObrigatoria(getJogador(jogadorAtual));
    	Set<Casas> chaves = this.obrigatoria.keySet(); 
		int max = 0;
		int cont=0;
    	for(Casas casa: chaves){
			cont = this.obrigatoria.get(casa);
			if(cont == max) this.listObrigatoriaInicial.add(casa);
			if(cont > max) {
				this.listObrigatoriaInicial.clear();
				this.listObrigatoriaInicial.add(casa);
				max = cont;
			}
		}
		if(listObrigatoriaInicial.isEmpty()){
			for(int i= 0; i< jogador.getCont(); i++){
				peça = jogador.getPeças(i);
				if(peça != null){
					this.adicionarJogadasPeçaDFS(peça,hash,n);
				}
			}
		}
		else{
			for(Casas casaI: listObrigatoriaInicial){
				casaInicial = casaI;
				criarListaCasasObrigatorias();
				List<Casas> listObrigatoria =listObrigatoriaFinal;
				for(Casas casaF: listObrigatoria){
					casaFinal = casaF;
					int posicao = casaF.getPos();
					int jogadorAux = jogadorAtual;
					boolean dama = casaI.getPeça().isDama();
					Tabuleiro tabuleiro = new Tabuleiro(tabuleiroAtual.casa, tabuleiroAtual.movimentos, tabuleiroAtual.avaliacao,tabuleiroAtual.jogadorA,tabuleiroAtual.jogadorB, casaI,casaF);
					tabuleiro.capturaPeça(dama);
					cont = tabuleiro.verificarObrigatoriedadeAcao(posicao,posicao,jogadorAux,dama,true);
					while(cont>0){
						tabuleiro.casaInicial = tabuleiro.casa[tabuleiro.casaFinal.getPos()];
						tabuleiro.criarListaCasasObrigatorias();
						tabuleiro.casaFinal = tabuleiro.listObrigatoriaFinal.get(0);
						tabuleiro.capturaPeça(dama);
						cont = tabuleiro.verificarObrigatoriedadeAcao(tabuleiro.casaFinal.getPos(),tabuleiro.casaFinal.getPos(),jogadorAux,dama,true);
					}
					
					tabuleiro.avaliacao = avaliacao(tabuleiro);
					tabuleiro.id=contadorPossibilidades;
					tabuleiro.paiID=tabuleiroAtual.id;
					hash.put(contadorPossibilidades, tabuleiro);
					contadorPossibilidades++;
					if(tabuleiro.movimentos<n){
						Tabuleiro tabuleiroAux = tabuleiroAtual;
						tabuleiroAtual = new Tabuleiro(tabuleiro.casa, tabuleiro.movimentos, tabuleiro.avaliacao,tabuleiro.jogadorA,tabuleiro.jogadorB);
						tabuleiroAtual.id = contadorPossibilidades-1;
						Jogador jogadorAdversario;
						if(jogadorAtual == 1) jogadorAdversario = tabuleiro.jogadorB;
						else jogadorAdversario = tabuleiro.jogadorA;
						tabuleiro.adicionarJogadasDoJogadorDFS(jogadorAdversario,hash,n);
						tabuleiroAtual = tabuleiroAux;
					}
				}
			}
		}
	}
	
	/**
	 * Adiciona na hash os tabuleiros gerados a partir da peça fornecida
	 * @param peça
	 * @param hash
	 * @param heuristica
	 */
	
	void adicionarJogadasPeçaDFS(Peças peça, Map<Integer, Tabuleiro> hash, int n) {
		int posicaoInicial = peça.getPosicao();
		List<Casas> listCasas = listaMovimentoValido(posicaoInicial, peça.isDama(), this);
		if(listCasas ==null) return;
		int i =0;
		for(Casas casaF: listCasas){
			Tabuleiro tabuleiro = new Tabuleiro(tabuleiroAtual.casa, tabuleiroAtual.movimentos, tabuleiroAtual.avaliacao,tabuleiroAtual.jogadorA,tabuleiroAtual.jogadorB);
			if(tabuleiro.moverPeça(posicaoInicial, casaF.getPos(), jogadorAtual, tabuleiro)){
				tabuleiro.tornarDama(tabuleiro.casa[casaF.getPos()].getPeça(),jogadorAtual);
				i++;
				tabuleiro.movimentos++;
				tabuleiro.avaliacao = tabuleiro.avaliacao(tabuleiro);
				tabuleiro.id=contadorPossibilidades;
				tabuleiro.paiID=tabuleiroAtual.id;
				hash.put(contadorPossibilidades, tabuleiro);
				contadorPossibilidades++;
				if(tabuleiro.movimentos<n){
					Tabuleiro tabuleiroAux = tabuleiroAtual;
					tabuleiroAtual = new Tabuleiro(tabuleiro.casa, tabuleiro.movimentos, tabuleiro.avaliacao,tabuleiro.jogadorA,tabuleiro.jogadorB);
					tabuleiroAtual.id = contadorPossibilidades-1;
					Jogador jogadorAdversario;
					if(jogadorAtual == 1) jogadorAdversario = tabuleiro.jogadorB;
					else jogadorAdversario = tabuleiro.jogadorA;
					tabuleiro.adicionarJogadasDoJogadorDFS(jogadorAdversario,hash,n);
					tabuleiroAtual = tabuleiroAux;
				}
			}
		}
	}
	
	/**
	 * Função de avaliação utilizada nos métodos de busca BFS e DFS. Esse método só leva em consideração o número de peças de cada jogador.
	 * @param tabuleiro
	 * @return a avaliação do tabuleiro
	 */
	int avaliacao(Tabuleiro tabuleiro){
		int x=0;
		if(jogadorAtual ==1){
			if(tabuleiroAtual.jogadorA.getContPeçasTabuleiro()> tabuleiro.jogadorA.getContPeçasTabuleiro()) x=avaliacao-1;
			if(tabuleiroAtual.jogadorB.getContPeçasTabuleiro()> tabuleiro.jogadorB.getContPeçasTabuleiro()) x=avaliacao+1;		
		}
		else{
			if(tabuleiroAtual.jogadorA.getContPeçasTabuleiro()> tabuleiro.jogadorA.getContPeçasTabuleiro()) x=avaliacao+1;
			if(tabuleiroAtual.jogadorB.getContPeçasTabuleiro()> tabuleiro.jogadorB.getContPeçasTabuleiro()) x=avaliacao-1;	
		}
		return x;
	}
	/**
	 * Função de avaliação utilizada para a heurística. Esse método se baseia em uma análise posicional das peças no tabuleiro.
	 * @param tabuleiro
	 * @return
	 */
	int calcularValor(Tabuleiro tabuleiro){
		int valorA=0, valorB = 0;
		int[] tabelaPesos={4,0,4,0,4,0,4,0,0,3,0,3,0,3,0,4,4,0,2,0,2,0,3,0,0,3,0,1,0,2,0,4,4,0,2,0,1,0,3,0,0,3,0,2,0,2,0,4,4,0,3,0,3,0,3,0,0,4,0,4,0,4,0,4};
		
		int somatorio = 0;
		int somatorioA = 0;
		int somatorioB = 0;
		int posA =0;
		int posB =0;
		for(int i = 0; i<12; i++){
			if(tabuleiro.jogadorA.getPeças(i)!=null){
				posA = tabuleiro.jogadorA.getPeças(i).getPosicao();
				if(posA>=57 && posA<=63){
					valorA = 10;
				}
				else {
					if(posA>=48 && posA<=55){
						valorA =7;
					}else valorA = 5;
				}
			} 
			if(tabuleiro.jogadorB.getPeças(i)!=null){
				posB= tabuleiro.jogadorB.getPeças(i).getPosicao();
				if(posB>=0 && posB<6){
					valorB = 10;
				}
				else {
					if(posB>=9 && posB<=15){
						valorB =7;
					}
					else valorB = 5;
				}
			}
			somatorioA +=(valorA*tabelaPesos[posA]);
			somatorioB +=(valorB*tabelaPesos[posB]);
		}
		somatorio = somatorioA - somatorioB;
		return somatorio;
	}
	
	/**
	 * Inicia o tabuleiro sem peças
	 */
	void iniciarTabuleiroVazio(){
		int linha =1;
		Peças peça = null;
		for(int i = 0; i<64; i++){
			if(i % 8 ==0) linha++;
			if(i % 2 ==0 && linha % 2 == 0){                        
				peça = null;
				this.casa[i] = new Casas(peça,i);
			}
			else {
				if(i % 2 ==1 && linha % 2 == 1){                    
					peça = null;
					this.casa[i] = new Casas(peça,i);
				}
				else{                                 
					this.casa[i] = new Casas(i);
				}
			}
		}
	}
	
	
	/**
	 * Inicia o tabuleiro colocando as peças de cada jogador nas devidas posições inicias
	 */
	public boolean iniciarTabuleiro(){
		int id = 0;
		int jogadorId = 1;
		int linha =1;
		
		Peças peça = null;
		
		for(int i = 0; i<64; i++){
			if(i % 8 ==0) linha++;
			if(i % 2 ==0 && linha % 2 == 0){                       
				if(i<23 || i>39){                                   
					if(i>39) jogadorId = -1;
					peça = new Peças(id, jogadorId, i,false);
					this.casa[i] = new Casas(peça,i);
					this.getJogador(jogadorId).addPeça(peça);
					id++;
				}
				else{                                               				
					peça = null;
					this.casa[i] = new Casas(peça,i);
				}
			}
			else if(i % 2 ==1 && linha % 2 == 1){                    
					if(i<23 || i>39){                                
						if(i>39) jogadorId = -1;
						peça = new Peças(id, jogadorId, i,false);
						this.casa[i] = new Casas(peça,i);
						this.getJogador(jogadorId).addPeça(peça);
						id++;
					}
					else{                             					
						peça = null;
						this.casa[i] = new Casas(peça,i);
					}
				}
				else{                                
					this.casa[i] = new Casas(i);
				}
			
		}
		return true;
	}
	
	/**
	 * Verifica se uma peça deve se tornar dama, e se for o caso transforma a peça.
	 * @param peça
	 * @param jogador
	 * @return true se a peça virar dama e false no caso contrário
	 */
	public boolean tornarDama(Peças peça, int jogador){
		int posicao = peça.getPosicao();
		if(jogador ==1){
			if(posicao == 63 || posicao == 61 || posicao == 59 || posicao == 57){
				peça.setDama(true);
				return true;
			}
		}
		else{
			if(posicao == 0 || posicao == 2 || posicao == 4 || posicao == 6){
				peça.setDama(true);
				return true;
			}
		}
		return false;
	}
	
	/**
	 * Verifica se um movimento é válido
	 * @param posicaoInicial
	 * @param posicaoFinal
	 * @param jogador
	 * @return true se o movimento for válido e false no caso contrário.
	 */
	public boolean verificarMovimentoValido(int posicaoInicial, int posicaoFinal, int jogador){
		if(this.casa[posicaoInicial].getPeça().getJogador() != jogador) return false;
		if(posicaoFinal <0 || posicaoFinal>63) return false;
		
		int posicaoD = (posicaoInicial+(jogador*7));
		int posicaoE = (posicaoInicial+(jogador*9));
		int posicaoDR= (posicaoInicial+(-1*jogador*7));
		int posicaoER = (posicaoInicial+(-1*jogador*9));
		
		boolean direitaOK;
		boolean esquerdaOK;
		boolean direitaROK;
		boolean esquerdaROK;
		
		if(this.casa[posicaoFinal].getPeça() == null){
			if(this.casa[posicaoInicial].getPeça().isDama()){
				if(posicaoInicial < posicaoFinal){
					do{
						direitaOK= false;
						esquerdaOK= false;
						if(posicaoD>=0 && posicaoD<64){
							if(this.casa[posicaoD].isValida() == true && this.casa[posicaoD].getPeça() == null){
								if(posicaoD < posicaoFinal) {
									posicaoD +=7;
									direitaOK = true;
								}
								else direitaOK = false;
							}
						}
						if(posicaoE>=0 && posicaoE<64){
							if(this.casa[posicaoE].isValida() == true && this.casa[posicaoE].getPeça() == null){
								if(posicaoE < posicaoFinal) {
									posicaoE +=9;
									esquerdaOK = true;
								}
								else esquerdaOK = false;
							}
						}
					}while(direitaOK || esquerdaOK);
					
					do{
						direitaROK= false;
						esquerdaROK= false;
						if(posicaoDR>=0 && posicaoDR<64){
							if(this.casa[posicaoDR].isValida() == true && this.casa[posicaoDR].getPeça() == null){
								if(posicaoDR < posicaoFinal) {
									posicaoDR +=7;
									direitaROK = true;
								}
								else direitaROK = false;
							}
						}
						if(posicaoER>=0 && posicaoER<64){
							if(this.casa[posicaoER].isValida() == true && this.casa[posicaoER].getPeça() == null){
								if(posicaoER < posicaoFinal) {
									posicaoER +=9;
									esquerdaROK = true;
								}
								else esquerdaROK = false;
							}
						}
					}while(direitaROK || esquerdaROK);
				}
				else{
					do{
						direitaROK= false;
						esquerdaROK= false;
						if(posicaoDR>=0 && posicaoDR<64){
							if(this.casa[posicaoDR].isValida() == true && this.casa[posicaoDR].getPeça() == null){
								if(posicaoDR > posicaoFinal) {
									posicaoDR -=7;
									direitaROK = true;
								}
								else direitaROK = false;
							}
						}
						if(posicaoER>=0 && posicaoER<64){
							if(this.casa[posicaoER].isValida() == true && this.casa[posicaoER].getPeça() == null){
								if(posicaoER > posicaoFinal) {
									posicaoER -=9;
									esquerdaROK = true;
								}
								else esquerdaROK = false;
							}
						}
					}while(direitaROK || esquerdaROK);
					do{
						direitaOK= false;
						esquerdaOK= false;
						if(posicaoD>=0 && posicaoD<64){
							if(this.casa[posicaoD].isValida() == true && this.casa[posicaoD].getPeça() == null){
								if(posicaoD > posicaoFinal) {
									posicaoD -=7;
									direitaOK = true;
								}
								else direitaOK = false;
							}
						}
						if(posicaoE>=0 && posicaoE<64){
							if(this.casa[posicaoE].isValida() == true && this.casa[posicaoE].getPeça() == null){
								if(posicaoE > posicaoFinal) {
									posicaoE -=9;
									esquerdaOK = true;
								}
								else esquerdaOK = false;
							}	
						}
					}while(direitaOK || esquerdaOK);
				}
				if(posicaoD == posicaoFinal) return true;
				if(posicaoE == posicaoFinal) return true;
				if(posicaoDR == posicaoFinal) return true;
				if(posicaoER == posicaoFinal) return true;
			}
			else{			
				if(posicaoD == posicaoFinal || posicaoE == posicaoFinal){
					
					if(this.casa[posicaoFinal].isValida() == true && this.casa[posicaoFinal].getPeça() == null) {
						return true;
					}
				}
			}
		}
		
		return false;
	}
	
	/**
	 * Função que encontra a lista de movimentos validos para uma peça
	 * @param posicaoInicial
	 * @param dama
	 * @param tabuleiro
	 * @return lista de movimentos válidos
	 */
	public List<Casas> listaMovimentoValido(int posicaoInicial, boolean dama, Tabuleiro tabuleiro){
		List<Casas> listCasas = new ArrayList<Casas>();
		if(tabuleiro.casa[posicaoInicial].getPeça().getJogador() != jogadorAtual) return null;
		
		int posicaoFinalD =posicaoInicial+(jogadorAtual*7);
		int posicaoFinalE =posicaoInicial+(jogadorAtual*9);
		int posicaoFinalDR =posicaoInicial+(-1*jogadorAtual*7);
		int posicaoFinalER =posicaoInicial+(-1*jogadorAtual*9);
		if(dama) {
			if(jogadorAtual ==1){
				if(posicaoFinalD>=0 && posicaoFinalD<64){
					do{
						if(tabuleiro.casa[posicaoFinalD].getPeça() == null && tabuleiro.casa[posicaoFinalD].isValida()) listCasas.add(tabuleiro.casa[posicaoFinalD]);
						else break;
						posicaoFinalD +=7;
					}while(posicaoFinalD <=54);
				}
				if(posicaoFinalE>=0 && posicaoFinalE<64){
					do{
						if(tabuleiro.casa[posicaoFinalE].getPeça() == null && tabuleiro.casa[posicaoFinalE].isValida()) listCasas.add(tabuleiro.casa[posicaoFinalE]);
						else break;
						posicaoFinalD +=9;
					}while(posicaoFinalD <=54);
				}
				if(posicaoFinalDR>=0 && posicaoFinalDR<64){
					do{
						if(tabuleiro.casa[posicaoFinalDR].getPeça() == null && tabuleiro.casa[posicaoFinalDR].isValida()) listCasas.add(tabuleiro.casa[posicaoFinalDR]);
						else break;
						posicaoFinalDR-=7;
					}while(posicaoFinalDR>=9);
				}
				if(posicaoFinalER>=0 && posicaoFinalER<64){
					do{
						if(tabuleiro.casa[posicaoFinalER].getPeça() == null && tabuleiro.casa[posicaoFinalER].isValida()) listCasas.add(tabuleiro.casa[posicaoFinalER]);
						else break;
						posicaoFinalER-=9;
					}while(posicaoFinalER>=9);
				}
			}else{
				if(posicaoFinalD>=0 && posicaoFinalD<64){
					do{
						if(tabuleiro.casa[posicaoFinalD].getPeça() == null && tabuleiro.casa[posicaoFinalD].isValida()) listCasas.add(tabuleiro.casa[posicaoFinalD]);
						else break;
						posicaoFinalD -=7;
					}while(posicaoFinalD >=9);
				}
				if(posicaoFinalE>=0 && posicaoFinalE<64){
					do{
						if(tabuleiro.casa[posicaoFinalE].getPeça() == null && tabuleiro.casa[posicaoFinalE].isValida()) listCasas.add(tabuleiro.casa[posicaoFinalE]);
						else break;
						posicaoFinalD -=9;
					}while(posicaoFinalD >=9);
				}
				if(posicaoFinalDR>=0 && posicaoFinalDR<64){
					do{
						if(tabuleiro.casa[posicaoFinalDR].getPeça() == null && tabuleiro.casa[posicaoFinalDR].isValida()) listCasas.add(tabuleiro.casa[posicaoFinalDR]);
						else break;
						posicaoFinalDR+=7;
					}while(posicaoFinalDR<=54);
				}
				if(posicaoFinalER>=0 && posicaoFinalER<64){
					do{
						if(tabuleiro.casa[posicaoFinalER].getPeça() == null && tabuleiro.casa[posicaoFinalER].isValida()) listCasas.add(tabuleiro.casa[posicaoFinalER]);
						else break;
						posicaoFinalER+=9;
					}while(posicaoFinalER<=54);
				}
			}
		}
		else{
			if(posicaoFinalD>=0 && posicaoFinalD<64){
				if(tabuleiro.verificarMovimentoValido(posicaoInicial, posicaoFinalD, jogadorAtual)){
					listCasas.add(tabuleiro.casa[posicaoFinalD]);
				}
			}
			if(posicaoFinalE>=0 && posicaoFinalE<64){
				if(tabuleiro.verificarMovimentoValido(posicaoInicial, posicaoFinalE, jogadorAtual)){
					listCasas.add(tabuleiro.casa[posicaoFinalE]);
				}
			}
		}
		return listCasas;
	}
	
	/**
	 * Função que verifica se uma peça é obrigada a capturar outra
	 * @param posicaoInicial
	 * @param posicao
	 * @param jogador
	 * @param dama
	 * @param continuo (true se uma peça ja tiver sido capturada)
	 * @return o número de peças que devem ser capturadas
	 */
	int verificarObrigatoriedadeAcao(int posicaoInicial, int posicao, int jogador, boolean dama, boolean continuo){
		int ganhoDireitaA = 0;
		int ganhoEsquerdaA = 0;
		int ganhoDireitaR = 0;
		int ganhoEsquerdaR = 0;
		int max=0;
		int posicaoFinalD =posicao+(jogadorAtual*(7+7));
		int posicaoFinalE =posicao+(jogadorAtual*(9+9));
		int posicaoFinalDR =posicao+(-1*jogadorAtual*(7+7));
		int posicaoFinalER =posicao+(-1*jogadorAtual*(9+9));
		int i;
		if(dama) {
			if(jogadorAtual ==1){
				for(i=1; posicaoFinalD <=54; i++) posicaoFinalD +=7;
				if(posicaoFinalD>=0 && posicaoFinalD<64){
					while(this.casa[posicaoFinalD].getPeça()!=null){
						posicaoFinalD -=7;
						if(posicaoFinalD<0 || posicaoFinalD>=64) break;
					}
				}
						
				for(i=1; posicaoFinalE <=54; i++) posicaoFinalE +=9;
				if(posicaoFinalE>=0 && posicaoFinalE<64){
					while(this.casa[posicaoFinalE].getPeça()!=null){
						posicaoFinalE -=9;
						if(posicaoFinalE<0 || posicaoFinalE>=64) break;
					}
				}
				for(i=1; posicaoFinalDR >=9; i++) posicaoFinalDR -=7;
				if(posicaoFinalDR>=0 && posicaoFinalDR<64){
					while(this.casa[posicaoFinalDR].getPeça()!=null){
						posicaoFinalDR +=7;
						if(posicaoFinalDR<0 || posicaoFinalDR>=64) break;
					}
				}
				for(i=1; posicaoFinalER >=9; i++) posicaoFinalER -=9;
				if(posicaoFinalER>=0 && posicaoFinalER<64){
					while(this.casa[posicaoFinalER].getPeça()!=null){
						posicaoFinalER +=9;
						if(posicaoFinalER<0 || posicaoFinalER>=64) break;
					}
				}
			}else{
				for(i=1; posicaoFinalD >=9; i++) posicaoFinalD -=7;
				if(posicaoFinalD>=0 && posicaoFinalD<64){
					while(this.casa[posicaoFinalD].getPeça()!=null){
						posicaoFinalD +=7;
						if(posicaoFinalD<0 || posicaoFinalD>=64) break;
					}
				}
						
				for(i=1; posicaoFinalE>=9; i++) posicaoFinalE -=9;
				if(posicaoFinalE>=0 && posicaoFinalE<64){
					while(this.casa[posicaoFinalE].getPeça()!=null){
						posicaoFinalE +=9;
						if(posicaoFinalE<0 || posicaoFinalE>=64) break;
					}
				}
				for(i=1; posicaoFinalDR <=54; i++) posicaoFinalDR +=7;
				if(posicaoFinalDR>=0 && posicaoFinalDR<64){
					while(this.casa[posicaoFinalDR].getPeça()!=null){
						posicaoFinalDR -=7;
						if(posicaoFinalDR<0 || posicaoFinalDR>=64) break;
					}
				}
				for(i=1; posicaoFinalER <=54; i++) posicaoFinalER +=9;
				if(posicaoFinalER>=0 && posicaoFinalER<64){
					while(this.casa[posicaoFinalER].getPeça()!=null){
						posicaoFinalER -=9;
						if(posicaoFinalER<0 || posicaoFinalER>=64) break;
					}
				}
			}
		}
		ganhoDireitaA = verificarCapturaDireitaAtivo(posicaoInicial,posicao, posicaoFinalD, jogador, dama, continuo); 
		ganhoEsquerdaA = verificarCapturaEsquerdaAtivo(posicaoInicial,posicao, posicaoFinalE, jogador, dama, continuo);
		if(max< ganhoDireitaA) max = ganhoDireitaA;
		if(max< ganhoEsquerdaA) max = ganhoEsquerdaA;
		if(dama){
			ganhoDireitaR = verificarCapturaDireitaRetroativo(posicaoInicial,posicao, posicaoFinalDR, jogador, dama, continuo); 
			ganhoEsquerdaR = verificarCapturaEsquerdaRetroativo(posicaoInicial,posicao, posicaoFinalER, jogador, dama, continuo);
			if(max< ganhoDireitaR) max = ganhoDireitaR;
			if(max< ganhoEsquerdaR) max = ganhoEsquerdaR;
		}
		
		return max;
	}
	
	/**
	 * Verifica se uma peça é obrigada a realizar uma captura a direita
	 * @param posicaoInicial
	 * @param posicao
	 * @param posicaoFinal
	 * @param jogador
	 * @param dama
	 * @param continuo
	 * @return o número de peças que devem ser capturadas seguindo o caminho da direita 
	 */
	public int verificarCapturaDireitaAtivo(int posicaoInicial, int posicao, int posicaoFinal, int jogador, boolean dama, boolean continuo){
		int contDireitaA=0;
		int contEsquerdaA=0;
		int contEsquerdaR=0;
		if(this.casa[posicaoInicial].getPeça().getJogador() != jogador) return 0;
		
		if(posicaoFinal <0 || posicaoFinal>63) return 0;
		
		int posicaoD = (posicao+(jogador*7));
		
		boolean direitaOK;
		if(this.casa[posicaoFinal].getPeça() == null){
			if(dama){
				if(posicao < posicaoFinal){
					do{
						direitaOK= false;
						if(posicaoD>=0 && posicaoD<64){
							if(this.casa[posicaoD].isValida() == true && this.casa[posicaoD].getPeça() == null){
								if(posicaoD < posicaoFinal && !continuo) {
									posicaoD +=7;
									direitaOK = true;
								}
								else direitaOK = false;
							}
							else{
								if(posicaoD+7 <= posicaoFinal) {
									if(this.casa[posicaoD].isValida() && this.casa[posicaoD].getPeça() != null 
									&& this.casa[posicaoD].getPeça().getJogador() != jogador
									&& this.casa[posicaoD+7].isValida() && this.casa[posicaoD+7].getPeça() == null){
										posicaoD +=7;
										contDireitaA = contDireitaA + 1 + verificarCapturaDireitaAtivo(posicaoInicial,posicaoD,posicaoD+(jogador*(7+7)),jogador, dama, continuo);  
										contEsquerdaA = contEsquerdaA + 1 + verificarCapturaEsquerdaAtivo(posicaoInicial,posicaoD,posicaoD+(jogador*(9+9)),jogador, dama, continuo);
										contEsquerdaR = contEsquerdaR + 1 + verificarCapturaEsquerdaRetroativo(posicaoInicial,posicaoD,posicaoD+(-1*jogador*(9+9)),jogador, dama, continuo);
										direitaOK = false;
										if(contEsquerdaA < contEsquerdaR) contEsquerdaA =contEsquerdaR;
									}
									else direitaOK = false;
								}
							}
						}
												
					}while(direitaOK);
				}
				else{
					do{
						direitaOK= false;
						if(posicaoD>=0 && posicaoD<64){
							if(this.casa[posicaoD].isValida() == true && this.casa[posicaoD].getPeça() == null){
								if(posicaoD > posicaoFinal && !continuo) {
									posicaoD -=7;
									direitaOK = true;
								}
								else direitaOK = false;
							}
							else {
								if(posicaoD-7 >= posicaoFinal) {
									if(this.casa[posicaoD].isValida() && this.casa[posicaoD].getPeça() != null 
									&& this.casa[posicaoD].getPeça().getJogador() != jogador
									&& this.casa[posicaoD-7].isValida() && this.casa[posicaoD-7].getPeça() == null){
										posicaoD -=7;
										contDireitaA = contDireitaA + 1 + verificarCapturaDireitaAtivo(posicaoInicial,posicaoD,posicaoD+(jogador*(7+7)),jogador, dama, continuo);  
										contEsquerdaA = contEsquerdaA + 1 + verificarCapturaEsquerdaAtivo(posicaoInicial,posicaoD,posicaoD+(jogador*(9+9)),jogador, dama, continuo);
										contEsquerdaR = contEsquerdaR + 1 + verificarCapturaEsquerdaRetroativo(posicaoInicial,posicaoD,posicaoD+(-1*jogador*(9+9)),jogador, dama, continuo);
										direitaOK = false;
										if(contEsquerdaA < contEsquerdaR) contEsquerdaA =contEsquerdaR;
									}
									else direitaOK = false;
								}
							}
						}
					}while(direitaOK);
				}
			}
			else{
				if(posicaoD>=0 && posicaoD<64){
					if(this.casa[posicaoD].isValida() && this.casa[posicaoD].getPeça() != null 
					&& this.casa[posicaoD].getPeça().getJogador() != jogador
					&& this.casa[posicaoD+jogador*7].isValida() && this.casa[posicaoD+jogador*7].getPeça() == null){
						posicaoD +=(jogador*7);
						contEsquerdaA = contEsquerdaA + 1 + verificarCapturaEsquerdaAtivo(posicaoInicial,posicaoD,posicaoD+(jogador*(9+9)),jogador, dama, continuo);
						contDireitaA = contDireitaA + 1 + verificarCapturaDireitaAtivo(posicaoInicial,posicaoD,posicaoD+(jogador*(7+7)),jogador, dama, continuo);  
					}
				}
			}
		}
		
		return (contDireitaA > contEsquerdaA)? contDireitaA :contEsquerdaA;
	}
	
	/**
	 * Verifica se uma peça é obrigada a realizar uma captura a direita retroativa(para trás)
	 * @param posicaoInicial
	 * @param posicao
	 * @param posicaoFinal
	 * @param jogador
	 * @param dama
	 * @param continuo
	 * @return o número de peças que devem ser capturadas seguindo o caminho da direita retroativa
	 */	
	public int verificarCapturaDireitaRetroativo(int posicaoInicial, int posicao, int posicaoFinal, int jogador, boolean dama, boolean continuo){
		int contDireitaR=0;
		int contEsquerdaA=0;
		int contEsquerdaR=0;
		if(this.casa[posicaoInicial].getPeça().getJogador() != jogador) return 0;
		
		if(posicaoFinal <0 || posicaoFinal>63) return 0;
		
		int posicaoDR = (posicao+(-1*jogador*7));
		
		boolean direitaROK;
		
		if(this.casa[posicaoFinal].getPeça() == null){
			if(dama){
				if(posicao < posicaoFinal){
					do{
						direitaROK= false;
						if(posicaoDR>=0 && posicaoDR<64){
							if(this.casa[posicaoDR].isValida() == true && this.casa[posicaoDR].getPeça() == null){
								if(posicaoDR < posicaoFinal && !continuo) {
									posicaoDR +=7;
									direitaROK = true;
								}
								else direitaROK = false;
							}
							else{
								if(posicaoDR+7 <= posicaoFinal) {
									if(this.casa[posicaoDR].isValida() && this.casa[posicaoDR].getPeça() != null 
									&& this.casa[posicaoDR].getPeça().getJogador() != jogador
									&& this.casa[posicaoDR+7].isValida() && this.casa[posicaoDR+7].getPeça() == null){
										posicaoDR +=7;
										contDireitaR = contDireitaR + 1 + verificarCapturaDireitaRetroativo(posicaoInicial,posicaoDR,posicaoDR+(-1*jogador*(7+7)),jogador, dama, continuo);  
										contEsquerdaA = contEsquerdaA + 1 + verificarCapturaEsquerdaAtivo(posicaoInicial,posicaoDR,posicaoDR+(jogador*(9+9)),jogador, dama, continuo);
										contEsquerdaR = contEsquerdaR + 1 + verificarCapturaEsquerdaRetroativo(posicaoInicial,posicaoDR,posicaoDR+(-1*jogador*(9+9)),jogador, dama, continuo);
										direitaROK = false;
										if(contEsquerdaA < contEsquerdaR) contEsquerdaA =contEsquerdaR;
									}
									else direitaROK = false;
								}
							}
						}
					}while(direitaROK);
				}
				else{
					do{
						direitaROK= false;
						if(posicaoDR>=0 && posicaoDR<64){
							if(this.casa[posicaoDR].isValida() == true && this.casa[posicaoDR].getPeça() == null){
								if(posicaoDR > posicaoFinal && !continuo) {
									posicaoDR -=7;
									direitaROK = true;
								}
								else direitaROK = false;
							}
							else {
								if(posicaoDR-7 >= posicaoFinal) {
									if(this.casa[posicaoDR].isValida() && this.casa[posicaoDR].getPeça() != null 
									&& this.casa[posicaoDR].getPeça().getJogador() != jogador
									&& this.casa[posicaoDR-7].isValida() && this.casa[posicaoDR-7].getPeça() == null){
										posicaoDR -=(7);
										contDireitaR = contDireitaR + 1 + verificarCapturaDireitaRetroativo(posicaoInicial,posicaoDR,posicaoDR+(-1*jogador*(7+7)),jogador, dama, continuo);  
										contEsquerdaA = contEsquerdaA + 1 + verificarCapturaEsquerdaAtivo(posicaoInicial,posicaoDR,posicaoDR+(jogador*(9+9)),jogador, dama, continuo);
										contEsquerdaR = contEsquerdaR + 1 + verificarCapturaEsquerdaRetroativo(posicaoInicial,posicaoDR,posicaoDR+(-1*jogador*(9+9)),jogador, dama, continuo);
										direitaROK = false;
										if(contEsquerdaA < contEsquerdaR) contEsquerdaA =contEsquerdaR;
									}
									else direitaROK = false;
								}
							}
						}
					}while(direitaROK);
				}
			}
		}
		
		return (contDireitaR > contEsquerdaA)? contDireitaR :contEsquerdaA;
	}
	
	/**
	 * Verifica se uma peça é obrigada a realizar uma captura a esquerda
	 * @param posicaoInicial
	 * @param posicao
	 * @param posicaoFinal
	 * @param jogador
	 * @param dama
	 * @param continuo
	 * @return o número de peças que devem ser capturadas seguindo o caminho da esquerda
	 */	
	public int verificarCapturaEsquerdaAtivo(int posicaoInicial, int posicao, int posicaoFinal, int jogador, boolean dama, boolean continuo){
		int contDireitaA=0;
		int contDireitaR=0;
		int contEsquerdaA=0;
		if(this.casa[posicaoInicial].getPeça().getJogador() != jogador) return 0;
		
		if(posicaoFinal <0 || posicaoFinal>63) return 0;
		
		int posicaoE = (posicao+(jogador*9));
		
		boolean esquerdaOK;
		if(this.casa[posicaoFinal].getPeça() == null){
			if(dama){
				if(posicao < posicaoFinal){
					do{
						esquerdaOK= false;
						if(posicaoE>=0 && posicaoE<64){
							if(this.casa[posicaoE].isValida() == true && this.casa[posicaoE].getPeça() == null){
								if(posicaoE < posicaoFinal && !continuo) {
									posicaoE +=9;
									esquerdaOK = true;
								}
								else esquerdaOK = false;
							}
							else{
								if(posicaoE+9 <= posicaoFinal) {
									if(this.casa[posicaoE].isValida() && this.casa[posicaoE].getPeça() != null 
									&& this.casa[posicaoE].getPeça().getJogador() != jogador
									&& this.casa[posicaoE+9].isValida() && this.casa[posicaoE+9].getPeça() == null){
										posicaoE +=9;
										contEsquerdaA = contEsquerdaA + 1 + verificarCapturaEsquerdaAtivo(posicaoInicial,posicaoE,posicaoE+(jogador*(9+9)),jogador, dama, continuo);
										contDireitaA = contDireitaA + 1 + verificarCapturaDireitaAtivo(posicaoInicial,posicaoE,posicaoE+(jogador*(7+7)),jogador, dama, continuo);  
										contDireitaR = contDireitaR + 1 + verificarCapturaDireitaRetroativo(posicaoInicial,posicaoE,posicaoE+(-1*jogador*(7+7)),jogador, dama, continuo);
										esquerdaOK = false;
										if(contDireitaA < contDireitaR) contDireitaA =contDireitaR;
									}
									else esquerdaOK = false;
								}
							}
						}						
					}while(esquerdaOK);
				}
				else{
					do{
						esquerdaOK= false;
						if(posicaoE>=0 && posicaoE<64){
							if(this.casa[posicaoE].isValida() == true && this.casa[posicaoE].getPeça() == null){
								if(posicaoE > posicaoFinal && !continuo) {
									posicaoE -=9;
									esquerdaOK = true;
								}
								else esquerdaOK = false;
							}
							else {
								if(posicaoE-9 >= posicaoFinal) {
									if(this.casa[posicaoE].isValida() && this.casa[posicaoE].getPeça() != null 
									&& this.casa[posicaoE].getPeça().getJogador() != jogador
									&& this.casa[posicaoE-9].isValida() && this.casa[posicaoE-9].getPeça() == null){
										posicaoE -=9;
										contEsquerdaA = contEsquerdaA + 1 + verificarCapturaEsquerdaAtivo(posicaoInicial,posicaoE,posicaoE+(jogador*(9+9)),jogador, dama, continuo);
										contDireitaA = contDireitaA + 1 + verificarCapturaDireitaAtivo(posicaoInicial,posicaoE,posicaoE+(jogador*(7+7)),jogador, dama, continuo);  
										contDireitaR = contDireitaR + 1 + verificarCapturaDireitaRetroativo(posicaoInicial,posicaoE,posicaoE+(-1*jogador*(7+7)),jogador, dama, continuo);
										esquerdaOK = false;
										if(contDireitaA < contDireitaR) contDireitaA =contDireitaR;
									}
									else esquerdaOK = false;
								}
							}
						}
					}while(esquerdaOK);
				}
			}
			else{
				if(posicaoE>=0 && posicaoE<64){
					if(this.casa[posicaoE].isValida() && this.casa[posicaoE].getPeça() != null 
					&& this.casa[posicaoE].getPeça().getJogador() != jogador
					&& this.casa[posicaoE+jogador*9].isValida() && this.casa[posicaoE+jogador*9].getPeça() == null){
						posicaoE +=(jogador*9);
						contEsquerdaA = contEsquerdaA + 1 + verificarCapturaEsquerdaAtivo(posicaoInicial,posicaoE,posicaoE+(jogador*(9+9)),jogador, dama, continuo);
						contDireitaA = contDireitaA + 1 + verificarCapturaDireitaAtivo(posicaoInicial,posicaoE,posicaoE+(jogador*(7+7)),jogador, dama, continuo);  
					}
				}
			}
		}
		
		return (contDireitaA > contEsquerdaA)? contDireitaA :contEsquerdaA;
	}
	
	/**
	 * Verifica se uma peça é obrigada a realizar uma captura a esquerda retroativa
	 * @param posicaoInicial
	 * @param posicao
	 * @param posicaoFinal
	 * @param jogador
	 * @param dama
	 * @param continuo
	 * @return o número de peças que devem ser capturadas seguindo o caminho da esquerda retroativa
	 */
	public int verificarCapturaEsquerdaRetroativo(int posicaoInicial,int posicao, int posicaoFinal, int jogador, boolean dama, boolean continuo){
		int contDireitaA=0;
		int contDireitaR=0;
		int contEsquerdaR=0;
		if(this.casa[posicaoInicial].getPeça().getJogador() != jogador) return 0;
		if(posicaoFinal <0 || posicaoFinal>63) return 0;
		int posicaoER = (posicao+(-1*jogador*9));
		
		boolean esquerdaROK;
		
		if(this.casa[posicaoFinal].getPeça() == null){
			if(dama){
				if(posicao < posicaoFinal){
					do{
						esquerdaROK= false;
						if(posicaoER>=0 && posicaoER<64){
							if(this.casa[posicaoER].isValida() == true && this.casa[posicaoER].getPeça() == null){
								if(posicaoER < posicaoFinal && !continuo) {
									posicaoER +=9;
									esquerdaROK = true;
								}
								else esquerdaROK = false;
							}
							else{
								if(posicaoER+9 <= posicaoFinal) {
									if(this.casa[posicaoER].isValida() && this.casa[posicaoER].getPeça() != null 
									&& this.casa[posicaoER].getPeça().getJogador() != jogador
									&& this.casa[posicaoER+9].isValida() && this.casa[posicaoER+9].getPeça() == null){
										posicaoER +=9;
										contEsquerdaR = contEsquerdaR + 1 + verificarCapturaEsquerdaRetroativo(posicaoInicial,posicaoER,posicaoER+(-1*jogador*(9+9)),jogador, dama, continuo);
										contDireitaA = contDireitaA + 1 + verificarCapturaDireitaAtivo(posicaoInicial,posicaoER,posicaoER+(jogador*(7+7)),jogador, dama, continuo);  
										contDireitaR = contDireitaR + 1 + verificarCapturaDireitaRetroativo(posicaoInicial,posicaoER,posicaoER+(-1*jogador*(7+7)),jogador, dama, continuo);
										esquerdaROK = false;
										if(contDireitaA < contDireitaR) contDireitaA =contDireitaR;
									}
									else esquerdaROK = false;
								}
							}
						}
					}while(esquerdaROK);
				}
				else{
					do{
						esquerdaROK= false;
						if(posicaoER>=0 && posicaoER<64){
							if(this.casa[posicaoER].isValida() == true && this.casa[posicaoER].getPeça() == null){
								if(posicaoER > posicaoFinal && !continuo) {
									posicaoER -=9;
									esquerdaROK = true;
								}
								else esquerdaROK = false;
							}
							else {
								if(posicaoER-9 >= posicaoFinal) {
									if(this.casa[posicaoER].isValida() && this.casa[posicaoER].getPeça() != null 
									&& this.casa[posicaoER].getPeça().getJogador() != jogador
									&& this.casa[posicaoER-9].isValida() && this.casa[posicaoER-9].getPeça() == null){
										posicaoER -=9;
										contEsquerdaR = contEsquerdaR + 1 + verificarCapturaEsquerdaRetroativo(posicaoInicial,posicaoER,posicaoER+(-1*jogador*(9+9)),jogador, dama, continuo);
										contDireitaA = contDireitaA + 1 + verificarCapturaDireitaAtivo(posicaoInicial,posicaoER,posicaoER+(jogador*(7+7)),jogador, dama, continuo);  
										contDireitaR = contDireitaR + 1 + verificarCapturaDireitaRetroativo(posicaoInicial,posicaoER,posicaoER+(-1*jogador*(7+7)),jogador, dama, continuo);
										esquerdaROK = false;
										if(contDireitaA < contDireitaR) contDireitaA =contDireitaR;
									}
									else esquerdaROK = false;
								}
							}
						}
					}while(esquerdaROK);
				}
			}
		}
		
		return (contDireitaA > contEsquerdaR)? contDireitaA :contEsquerdaR;
	}
	
	/**
	 * Verifica se uma peça é obrigada a realizar uma captura a direita
	 * @param posicaoInicial
	 * @param posicao
	 * @param posicaoFinal
	 * @param jogador
	 * @param dama
	 * @param continuo
	 * @return true se a peça for obrigada a realizar a captura a direita
	 */
	public boolean verificaCapturaDireitaAtivo(int posicaoInicial, int posicaoFinal, int jogador){
		if(posicaoInicial <0 || posicaoInicial>63 || posicaoFinal<0 || posicaoFinal>63 ) return false;
		if(this.casa[posicaoInicial].getPeça().getJogador() != jogador) return false;
		if(this.casa[posicaoInicial].getPeça()== null) return false;
		
		int proxPosicao =(posicaoInicial+(jogador*7)); 
		int posicaoCaptura = posicaoFinal -(jogador*7);  
		
		if(this.casa[posicaoCaptura].getPeça()== null) return false;
		boolean direitaOK;
		if(this.casa[posicaoInicial].getPeça().isDama()){
			do{
				direitaOK = false;
				if(this.casa[proxPosicao].isValida() == true && this.casa[proxPosicao].getPeça() == null){
					if(proxPosicao < posicaoCaptura && jogador == 1) {
						proxPosicao = proxPosicao +(jogador*7);
						direitaOK = true;
					}
					else if(proxPosicao > posicaoCaptura && jogador == -1){
						proxPosicao = proxPosicao +(jogador*7);
						direitaOK = true;
					}
					else direitaOK = false;
				}
			}while(direitaOK);
		}
		proxPosicao = proxPosicao +(jogador*7);
		if(proxPosicao == posicaoFinal){
			if(this.casa[posicaoCaptura].getPeça()!= null && this.casa[proxPosicao].getPeça() == null) return true;
		}
		return false;
	}
	
	/**
	 * Verifica se uma peça é obrigada a realizar uma captura a direita retroativa
	 * @param posicaoInicial
	 * @param posicao
	 * @param posicaoFinal
	 * @param jogador
	 * @param dama
	 * @param continuo
	 * @return true se a peça for obrigada a realizar a captura a direita retroativa
	 */
	public boolean verificaCapturaDireitaRetroativo(int posicaoInicial, int posicaoFinal, int jogador){
		if(posicaoInicial <0 || posicaoInicial>63 || posicaoFinal<0 || posicaoFinal>63 ) return false;
		if(this.casa[posicaoInicial].getPeça().getJogador() != jogador) return false;
		if(this.casa[posicaoInicial].getPeça()== null) return false;
		
		int proxPosicao =(posicaoInicial+(-1*jogador*7)); 
		int posicaoCaptura = posicaoFinal -(-1*jogador*7);  
		
		if(this.casa[posicaoCaptura].getPeça()== null) return false;
		boolean direitaROK;
		if(this.casa[posicaoInicial].getPeça().isDama()){
			do{
				direitaROK = false;
				if(this.casa[proxPosicao].isValida() == true && this.casa[proxPosicao].getPeça() == null){
					if(proxPosicao > posicaoCaptura && jogador == 1) {
						proxPosicao = proxPosicao -(jogador*7);
						direitaROK = true;
					}
					else if(proxPosicao < posicaoCaptura && jogador == -1){
							proxPosicao = proxPosicao -(jogador*7);
							direitaROK = true;
						}
						else direitaROK = false;
				}
			}while(direitaROK);
		}
		proxPosicao = proxPosicao -(jogador*7);
		if(proxPosicao == posicaoFinal){
			if(this.casa[posicaoCaptura].getPeça()!= null && this.casa[proxPosicao].getPeça() == null) return true;
		}
		return false;
	}
	
	/**
	 * Verifica se uma peça é obrigada a realizar uma captura a esquerda
	 * @param posicaoInicial
	 * @param posicao
	 * @param posicaoFinal
	 * @param jogador
	 * @param dama
	 * @param continuo
	 * @return true se a peça for obrigada a realizar a captura a esquerda
	 */
	
	public boolean verificaCapturaEsquerdaAtivo(int posicaoInicial, int posicaoFinal, int jogador){
		if(posicaoInicial <0 || posicaoInicial>63 || posicaoFinal<0 || posicaoFinal>63 ) return false;
		if(this.casa[posicaoInicial].getPeça().getJogador() != jogador) return false;
		if(this.casa[posicaoInicial].getPeça()== null) return false;
		
		int proxPosicao =(posicaoInicial+(jogador*9)); 
		int posicaoCaptura = posicaoFinal -(jogador*9);  
		
		if(this.casa[posicaoCaptura].getPeça()== null) return false;
		boolean esquerdaOK;
		if(this.casa[posicaoInicial].getPeça().isDama()){
			do{
				esquerdaOK = false;
				if(this.casa[proxPosicao].isValida() == true && this.casa[proxPosicao].getPeça() == null){
					if(proxPosicao < posicaoCaptura && jogador == 1) {
						proxPosicao = proxPosicao +(jogador*9);
						esquerdaOK = true;
					}
					else if(proxPosicao > posicaoCaptura && jogador == -1){
							proxPosicao = proxPosicao +(jogador*9);
							esquerdaOK = true;
						}
						else esquerdaOK = false;
				}
			}while(esquerdaOK);
		}
		proxPosicao = proxPosicao +(jogador*9);
		if(proxPosicao == posicaoFinal){
			if(this.casa[posicaoCaptura].getPeça()!= null && this.casa[proxPosicao].getPeça() == null) return true;
		}
		return false;
	}
	
	/**
	 * Verifica se uma peça é obrigada a realizar uma captura a esquerda retroativa
	 * @param posicaoInicial
	 * @param posicao
	 * @param posicaoFinal
	 * @param jogador
	 * @param dama
	 * @param continuo
	 * @return true se a peça for obrigada a realizar a captura a esquerda retroativa
	 */
	public boolean verificaCapturaEsquerdaRetroativo(int posicaoInicial, int posicaoFinal, int jogador){
		if(posicaoInicial <0 || posicaoInicial>63 || posicaoFinal<0 || posicaoFinal>63 ) return false;
		if(this.casa[posicaoInicial].getPeça().getJogador() != jogador) return false;
		if(this.casa[posicaoInicial].getPeça()== null) return false;
		int proxPosicao =(posicaoInicial+(-1*jogador*9)); 
		int posicaoCaptura = posicaoFinal -(-1*jogador*9); 
		if(this.casa[posicaoCaptura].getPeça()== null) return false;
		boolean esquerdaROK;
		if(this.casa[posicaoInicial].getPeça().isDama()){
			do{
				esquerdaROK = false;
				if(this.casa[proxPosicao].isValida() == true && this.casa[proxPosicao].getPeça() == null){
					if(proxPosicao > posicaoCaptura && jogador == 1) {
						proxPosicao = proxPosicao - (jogador*9);
						esquerdaROK = true;
					}
					else if(proxPosicao < posicaoCaptura && jogador == -1){
							proxPosicao = proxPosicao -(jogador*9);
							esquerdaROK = true;
						}
					else esquerdaROK = false;
				}
			}while(esquerdaROK);
		}
		proxPosicao = proxPosicao -(jogador*9);
		if(proxPosicao == posicaoFinal){
			if(this.casa[posicaoCaptura].getPeça()!= null && this.casa[proxPosicao].getPeça() == null) return true;
		}
		return false;
	}
	
	/**
	 * Função que move uma peça do tabuleiro
	 * @param posicaoInicial
	 * @param posicaoFinal
	 * @param jogador
	 * @return true se for possível mover a peça
	 */
	public boolean moverPeça(int posicaoInicial, int posicaoFinal, int jogador){
		if(this.verificarMovimentoValido(posicaoInicial,posicaoFinal, jogador)){
			Peças peça = this.casa[posicaoInicial].getPeça();
			peça.setPosicao(posicaoFinal);
			
			this.casa[posicaoFinal].setPeça(peça);
			this.casa[posicaoInicial].setPeça(null);                
			
			if(jogador==1) this.jogadorA.setPeça(peça);
			else this.jogadorB.setPeça(peça);	
			return true;
		}
		return false;
	}
	
	/**
	 * Função que move uma peça do tabuleiro
	 * @param posicaoInicial
	 * @param posicaoFinal
	 * @param jogador
	 * @param tabuleiro
	 * @return true se for possível mover a peça
	 */
	public boolean moverPeça(int posicaoInicial, int posicaoFinal, int jogador, Tabuleiro tabuleiro){
		if(tabuleiro.verificarMovimentoValido(posicaoInicial, posicaoFinal, jogador)){
			Peças peça = tabuleiro.casa[posicaoInicial].getPeça();
			peça.setPosicao(posicaoFinal);
			
			tabuleiro.casa[posicaoFinal].setPeça(peça);
			tabuleiro.casa[posicaoInicial].setPeça(null);         
			
			if(jogador==1) tabuleiro.jogadorA.setPeça(peça);
			else tabuleiro.jogadorB.setPeça(peça);	
			return true;
		}
		return false;
	}
	
	/**
	 * Função que verifica se um jogador é obrigado a realizar uma captura
	 * @param jogador
	 * @return Map contendo a casa e o número de peças capturadas seguindo o caminho dessa casa
	 */
	public Map<Casas, Integer> verificaObrigatoria(Jogador jogador) {
		Map<Casas, Integer> obrigatoria = new HashMap<Casas, Integer>();
		Peças peça;
		for(int i= 0; i< jogador.getCont(); i++){
			peça = jogador.getPeças(i);
			if(peça != null){
				int cont = this.verificarObrigatoriedadeAcao(peça.getPosicao(),peça.getPosicao(),peça.getJogador(),peça.isDama(),false);
				if(cont>0) {
					obrigatoria.put(this.casa[peça.getPosicao()], cont);
				}
			}
		}
		return obrigatoria;
	}
	
	/**
	 * Função que verifica se uma peça é obrigada a realizar uma captura
	 * @param peça
	 * @param continuo
	 * @return true se a peça for obrigada a realizar uma captura, e false no caso contrário
	 */
	public boolean verificaPeçaObrigatoria(Peças peça, boolean continuo) {
		if(peça != null){
			int cont = verificarObrigatoriedadeAcao(peça.getPosicao(),peça.getPosicao(),peça.getJogador(),peça.isDama(), continuo);
			if(cont>0) return true;
		}
		return false;
	}
	
	/**
	 * Função que cria uma lista de casas finais obrigatórias a partir da casa inicial selecionada
	 */
	public void criarListaCasasObrigatorias(){
    	listObrigatoriaFinal = new ArrayList<Casas>();
		int posicaoInicial = casaInicial.getPos();
	    int posicao = posicaoInicial;
		int cont;
		int posicaoFinalD =posicao+(jogadorAtual*(7+7));
		int posicaoFinalE =posicao+(jogadorAtual*(9+9));
		int posicaoFinalDR =posicao+(-1*jogadorAtual*(7+7));
		int posicaoFinalER =posicao+(-1*jogadorAtual*(9+9));
		int i;
		max = 0;
		if(casaInicial.getPeça().isDama()) {
			if(jogadorAtual ==1){
				for(i=1; posicaoFinalD <=54; i++) posicaoFinalD +=7;
				if(posicaoFinalD>=0 && posicaoFinalD<64){
					while(this.casa[posicaoFinalD].getPeça()!=null){
						posicaoFinalD -=7;
						if(posicaoFinalD<0 || posicaoFinalD>=64) break;
					}
				}
						
				for(i=1; posicaoFinalE <=54; i++) posicaoFinalE +=9;
				if(posicaoFinalE>=0 && posicaoFinalE<64){
					while(this.casa[posicaoFinalE].getPeça()!=null){
						posicaoFinalE -=9;
						if(posicaoFinalE<0 || posicaoFinalE>=64) break;
					}
				}
				for(i=1; posicaoFinalDR >=9; i++) posicaoFinalDR -=7;
				if(posicaoFinalDR>=0 && posicaoFinalDR<64){
					while(this.casa[posicaoFinalDR].getPeça()!=null){
						posicaoFinalDR +=7;
						if(posicaoFinalDR<0 || posicaoFinalDR>=64) break;
					}
				}
				for(i=1; posicaoFinalER >=9; i++) posicaoFinalER -=9;
				if(posicaoFinalER>=0 && posicaoFinalER<64){
					while(this.casa[posicaoFinalER].getPeça()!=null){
						posicaoFinalER +=9;
						if(posicaoFinalER<0 || posicaoFinalER>=64) break;
					}
				}
			}else{
				for(i=1; posicaoFinalD >=9; i++) posicaoFinalD -=7;
				if(posicaoFinalD>=0 && posicaoFinalD<64){
					while(this.casa[posicaoFinalD].getPeça()!=null){
						posicaoFinalD +=7;
						if(posicaoFinalD<0 || posicaoFinalD>=64) break;
					}
				}
						
				for(i=1; posicaoFinalE>=9; i++) posicaoFinalE -=9;
				if(posicaoFinalE>=0 && posicaoFinalE<64){
					while(this.casa[posicaoFinalE].getPeça()!=null){
						posicaoFinalE +=9;
						if(posicaoFinalE<0 || posicaoFinalE>=64) break;
					}
				}
				for(i=1; posicaoFinalDR <=54; i++) posicaoFinalDR +=7;
				if(posicaoFinalDR>=0 && posicaoFinalDR<64){
					while(this.casa[posicaoFinalDR].getPeça()!=null){
						posicaoFinalDR -=7;
						if(posicaoFinalDR<0 || posicaoFinalDR>=64) break;
					}
				}
				for(i=1; posicaoFinalER <=54; i++) posicaoFinalER +=9;
				if(posicaoFinalER>=0 && posicaoFinalER<64){
					while(this.casa[posicaoFinalER].getPeça()!=null){
						posicaoFinalER -=9;
						if(posicaoFinalER<0 || posicaoFinalER>=64) break;
					}
				}
			}
		}
		cont = this.verificarCapturaDireitaAtivo(posicaoInicial,posicaoInicial, posicaoFinalD, jogadorAtual, casaInicial.getPeça().isDama(), false); 
	    adicionaCasasFinaisListObrigatorias(posicaoFinalD,cont,posicao, jogadorAtual*7);
	    cont = this.verificarCapturaEsquerdaAtivo(posicaoInicial,posicaoInicial,posicaoFinalE, jogadorAtual, casaInicial.getPeça().isDama(), false); 
		adicionaCasasFinaisListObrigatorias(posicaoFinalE,cont,posicao, jogadorAtual*9);
		
		if(casaInicial.getPeça().isDama()){
			cont = this.verificarCapturaDireitaRetroativo(posicaoInicial,posicaoInicial, posicaoFinalDR, jogadorAtual, casaInicial.getPeça().isDama(), false); 
			adicionaCasasFinaisListObrigatorias(posicaoFinalDR,cont,posicao, -1*jogadorAtual*7);
			cont = this.verificarCapturaEsquerdaRetroativo(posicaoInicial,posicaoInicial, posicaoFinalER, jogadorAtual, casaInicial.getPeça().isDama(), false);
			adicionaCasasFinaisListObrigatorias(posicaoFinalER,cont,posicao, -1*jogadorAtual*9);
		}  
    }
	
	/**
	 * Função que adiciona as casas finais na lista criada pelo método criarListaCasasObrigatorias()
	 * @param posicaoFim
	 * @param cont
	 * @param posicao
	 * @param incremento
	 */
	public void adicionaCasasFinaisListObrigatorias(int posicaoFim, int cont, int posicao, int incremento){
    	int posicaoFinal = 0;
    	if(cont == max && cont !=0){
			if(casaInicial.getPeça().isDama()){
        		posicaoFinal= posicao+incremento;
				if(posicaoFinal>=0 && posicaoFinal<64){
					while(this.casa[posicaoFinal].getPeça()==null){
						posicaoFinal+=incremento;
						if(posicaoFinal<0 || posicaoFinal>=64) break;
					}
					
					posicaoFinal+=incremento;
					while(this.casa[posicaoFinal].getPeça()==null && this.casa[posicaoFinal].isValida()){
						listObrigatoriaFinal.add(this.casa[posicaoFinal]);
						posicaoFinal+=incremento;
						if(posicaoFinal<0 || posicaoFinal>=64) break;
					}
				}
			}
			else {
				listObrigatoriaFinal.add(this.casa[posicaoFim]);
			}
		}
		if(cont > max) {
			listObrigatoriaFinal.clear();
			if(casaInicial.getPeça().isDama()){
				posicaoFinal= posicao+incremento;
				if(posicaoFinal>=0 && posicaoFinal<64){
					while(this.casa[posicaoFinal].getPeça()==null){
						posicaoFinal+=incremento;
						if(posicaoFinal<0 || posicaoFinal>=64) break;
					}
					posicaoFinal+=incremento;
					while(this.casa[posicaoFinal].getPeça()==null  && this.casa[posicaoFinal].isValida()){
						listObrigatoriaFinal.add(this.casa[posicaoFinal]);
						posicaoFinal+=incremento;
						if(posicaoFinal<0 || posicaoFinal>=64) break;
					}
				}
			}
			else {
				listObrigatoriaFinal.add(this.casa[posicaoFim]);
			}
			max = cont;
		}
    }
	
	/**
	 * Função que realiza a captura de uma peça
	 * @param dama
	 */
	public void capturaPeça(boolean dama){
    	int posicaoInicial =this.casaInicial.getPos();
		int posicaoFinal =this.casaFinal.getPos();
		int posicaoCaptura = 0;
		int teste =-99;
		boolean direitaROK;
		boolean esquerdaROK;
		boolean direitaOK;
		boolean esquerdaOK;
		int posicaoD= (posicaoInicial+(jogadorAtual*7));
		int posicaoE= (posicaoInicial+(jogadorAtual*9));
		int posicaoDR= (posicaoInicial+(-1*jogadorAtual*7));
		int posicaoER= (posicaoInicial+(-1*jogadorAtual*9));
		if(posicaoInicial < posicaoFinal){
			do{
				direitaOK= false;
				
				if(posicaoD >=0 && posicaoD<64 ){
					if(this.casa[posicaoD].isValida() && this.casa[posicaoD].getPeça() == null && dama){
						if(posicaoD < posicaoFinal) {
							posicaoD+=7;
							direitaOK=true;
						}
						else direitaOK= false;
					}
					else{
						if(posicaoD+7 <=posicaoFinal){
							if(this.casa[posicaoD].isValida() && this.casa[posicaoD].getPeça() != null 
							&& this.casa[posicaoD].getPeça().getPosicao() != casaInicial.getPos()
							&& this.casa[posicaoD+7].isValida() && this.casa[posicaoD+7].getPeça() == null){
								direitaOK=true;
								if(posicaoFinal == posicaoD+7) direitaOK=false;
								teste= posicaoD+7;
								while(teste<posicaoFinal) teste+=7;
								if(posicaoFinal == teste){
									posicaoCaptura = posicaoD;
									casaCaptura = this.casa[posicaoCaptura];
								}
								posicaoD+=7;
							}
						}
					}
				}
			}while(direitaOK);
			do{
				esquerdaOK=false;
				if(posicaoE >=0 && posicaoE<64 ){
					if(this.casa[posicaoE].isValida() == true && this.casa[posicaoE].getPeça() == null && dama){
						if(posicaoE < posicaoFinal) {
							posicaoE +=9;
							esquerdaOK = true;
						}
						else esquerdaOK = false;
					}
					else{
						if(posicaoE+9 <=posicaoFinal){
							if(this.casa[posicaoE].isValida() && this.casa[posicaoE].getPeça() != null 
							&& this.casa[posicaoE].getPeça().getPosicao() != casaInicial.getPos()
							&& this.casa[posicaoE+9].isValida() && this.casa[posicaoE+9].getPeça() == null){
								esquerdaOK=true;
								if(posicaoFinal == posicaoE+9) esquerdaOK=false;
								teste= posicaoE+9;
								while(teste<posicaoFinal) teste+=9;
								if(posicaoFinal == teste){
									posicaoCaptura = posicaoE;
									casaCaptura = this.casa[posicaoCaptura];
								}
								posicaoE +=9;
							}
						}
					}
				}
			}while(esquerdaOK);
			if(dama){
				do{
					direitaROK= false;
					
					if(posicaoDR >=0 && posicaoDR<64 ){
						if(this.casa[posicaoDR].isValida() && this.casa[posicaoDR].getPeça() == null){
							if(posicaoDR < posicaoFinal) {
								posicaoDR+=7;
								direitaROK=true;
							}
							else direitaROK= false;
						}
						else{
							if(posicaoDR+7 <=posicaoFinal){
								if(this.casa[posicaoDR].isValida() && this.casa[posicaoDR].getPeça() != null 
								&& this.casa[posicaoDR].getPeça().getPosicao() != casaInicial.getPos()
								&& this.casa[posicaoDR+7].isValida() && this.casa[posicaoDR+7].getPeça() == null){
									direitaROK=true;
									if(posicaoFinal == posicaoDR+7) direitaROK=false;
									teste= posicaoDR+7;
									while(teste<posicaoFinal) teste+=7;
									if(posicaoFinal == teste){
										posicaoCaptura = posicaoDR;
										casaCaptura = this.casa[posicaoCaptura];
									}
									posicaoDR+=7;
								}								
							}
						}
					}
				}while(direitaROK);
				do{
					esquerdaROK=false;
					if(posicaoER >=0 && posicaoER<64 ){
						if(this.casa[posicaoER].isValida() == true && this.casa[posicaoER].getPeça() == null){
							if(posicaoER < posicaoFinal) {
								posicaoER +=9;
								esquerdaROK = true;
							}
							else esquerdaROK = false;
						}
						else{
							if(posicaoER+9 <=posicaoFinal){
								if(this.casa[posicaoER].isValida() && this.casa[posicaoER].getPeça() != null 
								&& this.casa[posicaoER].getPeça().getPosicao() != casaInicial.getPos()
								&& this.casa[posicaoER+9].isValida() && this.casa[posicaoER+9].getPeça() == null){
									esquerdaROK=true;
									if(posicaoFinal == posicaoER+9) esquerdaROK=false;
									teste= posicaoER+9;
									while(teste<posicaoFinal) teste+=9;
									if(posicaoFinal == teste){
										posicaoCaptura = posicaoER;
										casaCaptura = this.casa[posicaoCaptura];
									}
									posicaoER +=9;
								}
							}
						}
					}
				}while(esquerdaROK);
			}
		}
		else{
			if(dama){
				do{
					direitaROK= false;
					
					if(posicaoDR >=0 && posicaoDR<64 ){
						if(this.casa[posicaoDR].isValida() && this.casa[posicaoDR].getPeça() == null){
							if(posicaoDR > posicaoFinal) {
								posicaoDR-=7;
								direitaROK=true;
							}
							else direitaROK= false;
						}
						else{
							if(posicaoDR-7 >=posicaoFinal){
								if(this.casa[posicaoDR].isValida() && this.casa[posicaoDR].getPeça() != null 
								&& this.casa[posicaoDR].getPeça().getPosicao() != casaInicial.getPos()
								&& this.casa[posicaoDR-7].isValida() && this.casa[posicaoDR-7].getPeça() == null){
									direitaROK=true;
									if(posicaoFinal == posicaoDR-7) direitaROK=false;
									teste= posicaoDR-7;
									while(teste>posicaoFinal) teste-=7;
									if(posicaoFinal == teste){
										posicaoCaptura = posicaoDR;
										casaCaptura = this.casa[posicaoCaptura];
									}
									posicaoDR-=7;
								}
							}
						}
					}
				}while(direitaROK);
				do{
					esquerdaROK=false;
					if(posicaoER >=0 && posicaoER<64 ){
						if(this.casa[posicaoER].isValida() == true && this.casa[posicaoER].getPeça() == null){
							if(posicaoER > posicaoFinal) {
								posicaoER -=9;
								esquerdaROK = true;
							}
							else esquerdaROK = false;
						}
						else{
							if(posicaoER-9 >=posicaoFinal){
								if(this.casa[posicaoER].isValida() && this.casa[posicaoER].getPeça() != null 
								&& this.casa[posicaoER].getPeça().getPosicao() != casaInicial.getPos()
								&& this.casa[posicaoER-9].isValida() && this.casa[posicaoER-9].getPeça() == null){
									esquerdaROK=true;
									if(posicaoFinal == posicaoER-9) esquerdaROK=false;
									teste= posicaoER-9;
									while(teste>posicaoFinal) teste-=9;
									if(posicaoFinal == teste){
										posicaoCaptura = posicaoER;
										casaCaptura = this.casa[posicaoCaptura];
									}
									posicaoER -=9;
								}
							}
						}
					}
				}while(esquerdaROK);
			}
			do{
				direitaOK= false;
				if(posicaoD >=0 && posicaoD<64 ){
					if(this.casa[posicaoD].isValida() && this.casa[posicaoD].getPeça() == null && dama){
						if(posicaoD > posicaoFinal) {
							posicaoD-=7;
							direitaOK=true;
						}
						else direitaOK= false;
					}
					else{
						if(posicaoD-7 >=posicaoFinal){
							if(this.casa[posicaoD].isValida() && this.casa[posicaoD].getPeça() != null 
							&& this.casa[posicaoD].getPeça().getPosicao() != casaInicial.getPos()
							&& this.casa[posicaoD-7].isValida() && this.casa[posicaoD-7].getPeça() == null){
								direitaOK=true;
								if(posicaoFinal == posicaoD-7) direitaOK=false;
								teste= posicaoD-7;
								while(teste>posicaoFinal) teste-=7;
								if(posicaoFinal == teste){
									posicaoCaptura = posicaoD;
									casaCaptura = this.casa[posicaoCaptura];
								}
								posicaoD-=7;
							}
						}
					}
				}
			}while(direitaOK);
			do{
				esquerdaOK=false;
				if(posicaoE >=0 && posicaoE<64 ){
					if(this.casa[posicaoE].isValida() == true && this.casa[posicaoE].getPeça() == null && dama){
						if(posicaoE > posicaoFinal) {
							posicaoE -=9;
							esquerdaOK = true;
						}
						else esquerdaOK = false;
					}
					else{
						if(posicaoE-9 >=posicaoFinal){
							if(this.casa[posicaoE].isValida() && this.casa[posicaoE].getPeça() != null
							&& this.casa[posicaoE].getPeça().getPosicao() != casaInicial.getPos()
							&& this.casa[posicaoE-9].isValida() && this.casa[posicaoE-9].getPeça() == null){	
								esquerdaOK=true;
								if(posicaoFinal == posicaoE-9) esquerdaOK=false;
								teste= posicaoE-9;
								while(teste>posicaoFinal) teste-=9;
								if(posicaoFinal == teste){
									posicaoCaptura = posicaoE;
									casaCaptura = this.casa[posicaoCaptura];
									//System.out.println("esquerda: " + posicaoCaptura);
								}
								posicaoE -=9;
							}
						}
					}
				}
			}while(esquerdaOK);
		}
		
		//System.out.println("posicao inicial: " +posicaoInicial);
		//System.out.println("posicao captura: " +posicaoCaptura);
		//System.out.println("posicao final: " +posicaoFinal);
		this.getJogador(-1*jogadorAtual).removePeça(casaCaptura.getPeça());
		this.casa[posicaoInicial].getPeça().setPosicao(posicaoFinal); 
		this.casa[posicaoFinal].setPeça(casaInicial.getPeça());      
		
		
		
		this.casa[posicaoInicial].setPeça(null); 
		this.casa[posicaoCaptura].setPeça(null);	
		if(!this.verificaPeçaObrigatoria(this.casa[posicaoFinal].getPeça(),true)){
			this.tornarDama(this.casa[posicaoFinal].getPeça(),jogadorAtual);
			this.movimentos++;
			listObrigatoriaInicial.clear();
			listObrigatoriaFinal.clear();
		}
		this.getJogador(jogadorAtual).setPeça(this.casa[posicaoFinal].getPeça());
    }
	/**
	 * Função que verifica se o jogo terminou
	 * @return true se sim e false no caso contrário
	 */
	public boolean fimJogo(){
		int cont =0;
    	if(this.getJogador(this.jogadorAtual).getContPeçasTabuleiro() ==0 ||
           this.getJogador(this.jogadorAtual*-1).getContPeçasTabuleiro() ==0){
         		JOptionPane.showMessageDialog(null,"<html> <font color='black'>Parabéns jogador "+ -1*this.jogadorAtual+" você foi o vencedor!","Parabéns!",JOptionPane.OK_OPTION);
         		return true;
        } 
    	for(int i= 0; i<12; i++){
    		Peças peça = this.getJogador(this.jogadorAtual).getPeças(i);
    		if(peça !=null){
    			int posicaoInicial = peça.getPosicao();
    			List<Casas> listCasas = this.listaMovimentoValido(posicaoInicial, peça.isDama(), this);
    			if(listCasas !=null && !listCasas.isEmpty()) cont++;
    		}
    	}
    	if(cont ==0) {
    		JOptionPane.showMessageDialog(null,"<html> <font color='black'>Parabéns jogador "+ -1*this.jogadorAtual+" você foi o vencedor!","Parabéns!",JOptionPane.OK_OPTION);
    		return true;
    	}
    	return false;
	}
	
	/**
	 * Função que imprime o tabuleiro no console
	 */
	public void imprimirTabuleiro(){
		for(int i = 0; i<64; i++){
			if(this.casa[i].getPeça() !=null){
				System.out.println("Posição: " + this.casa[i].getPos() + " Peça: " + this.casa[i].getPeça().getId()+ " Jogador: " + this.casa[i].getPeça().getJogador());
			}
		}
	}
	
	/**
	 * Função que carrega um tabuleiro por um arquivo 
	 * @param arquivo
	 * @return
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public boolean carregarTabuleiro(String arquivo)
	throws FileNotFoundException, IOException {
		this.iniciarTabuleiroVazio();
		
		try{
			String linha;
			int id = 0;
			int posicao = 0;
			int jogadorId = 0;
			File file = new File(arquivo);

			if (!file.exists()) {
				return false;
			}

			BufferedReader br = new BufferedReader(new FileReader(arquivo));
		
			while( (linha = br.readLine()) != null ){
				String[] line = linha.split("[;]");
				int i = 0;
				for (String str  : line){
					i++;
					switch(i){
						case 1 : id = Integer.parseInt(str);
								break;
						case 2 : posicao = Integer.parseInt(str);
					 			break;
						case 3 : jogadorId = Integer.parseInt(str);
					 			break;
					}
				}
				Peças peça = new Peças(id, jogadorId, posicao, false);
				if(jogadorId == 1) this.jogadorA.addPeça(peça);
				else this.jogadorB.addPeça(peça);
				this.casa[posicao] = new Casas(peça,posicao);
			}
			br.close();
		}catch(NumberFormatException e){
			System.out.println("\n\nPrograma Finalizado!");
			System.exit(1);
		}
		return true;
	}
	/**
	 * Função que salva um tabuleiro em um arquivo
	 * @param arquivo
	 * @param adicionar
	 * @throws IOException
	 */
	public void salvarTabuleiro(String arquivo, boolean adicionar)
	throws IOException {
		File file = new File(arquivo);
		file.delete();
		FileWriter fw = new FileWriter(arquivo, adicionar);
		for (int i=0; i<64;i++) {
			if(this.casa[i].getPeça() !=null){
				fw.write(this.casa[i].getPeça().getId() + ";" + this.casa[i].getPos() + ";"  + this.casa[i].getPeça().getJogador() +";\n");				
			}
		}		
		fw.close();
	}

	
}
